<template>
    <div>Attr</div>
    <el-card>
        <category-selector :disabled="!isShowList"></category-selector>
    </el-card>
    <el-card>
        <div v-show="isShowList">
            <el-button type="primary" :icon="Plus" @click="showAdd" :disabled="!category3Id">添加属性</el-button>
            <el-table :data="attrList">
                <el-table-column label="序号" type="index" align="center" width="80"></el-table-column>
                <el-table-column label="属性名称" width="150" prop="attrName">
                </el-table-column>
                <el-table-column label="属性值列表">
                    <template v-slot="{ row }">
                        <el-tag v-for="value in row.attrValueList" :key="value.id" style="margin-right: 5px;">{{
                            value.valueName
                        }}</el-tag>
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="150">
                    <template v-slot="{ row }">
                        <el-button type="primary" :icon="Edit" size="small" @click="showUpdate(row)">
                        </el-button>
                        <el-popconfirm :title="`确定删除${row.attrName}`" @confirm="remove(row.Id)">
                            <template #reference>
                                <el-button type="danger" :icon="Delete" size="small">
                                </el-button>
                            </template>
                        </el-popconfirm>


                    </template>
                </el-table-column>
            </el-table>
        </div>

        <div v-show="!isShowList">
            <span>属性名</span>
            <el-input v-model="attr.attrName" style="width: 150px; margin-left: 15px;"></el-input>
            <div>
                <el-button type="primary" :icon="Plus" style="margin-top: 5px;" @click="addAttrValue">添加属性值</el-button>
                <el-button @click="isShowList = true" style="margin-top: 5px;">取消</el-button>
            </div>

            <el-table :data="attr.attrValueList">
                <el-table-column label="序号" type="index" width="80" align="center"></el-table-column>
                <el-table-column label="属性值名称">
                    <template #default="{ row, $index }">
                        <!-- 通过判断标识isEdit来确定是显示span还是显示input -->
                        <el-input v-if="row.isEdit" v-model="row.valueName" @blur="toShow(row, $index)"></el-input>
                        <span v-else @click="toEdit(row)">{{ row.valueName }}</span>
                    </template>

                </el-table-column>
                <el-table-column label="操作">
                    <template #default="{ $index }">
                        <el-button type="danger" :icon="Delete" size="small"
                            @click="attr.attrValueList.splice($index, 1)"></el-button>
                    </template>
                </el-table-column>

            </el-table>
            <div style="margin: 20px 0;">
                <el-button type="primary" @click="save" :disabled="isSaveDisabled">保存</el-button>
                <el-button @click="isShowList = true">取消</el-button>

            </div>
        </div>




       
        
    </el-card>
</template>

<script lang="ts">
import { deleteAttrApi, getAttrListApi, saveAttrApi } from '@/api/product/attr';
import type { AttrListModel, AttrModel, AttrValueModel } from '@/api/product/model/AttrModel';
import { useCategoryStore } from '@/stores/category';
import { Delete, Edit, Plus } from '@element-plus/icons-vue';
import { storeToRefs } from 'pinia';
import { computed, defineComponent, nextTick, reactive, ref, watch } from 'vue'
import { ElInput, ElMessage } from 'element-plus'
import { cloneDeep } from 'lodash';
import type { TrademarkModel } from '@/api/product/model/trademarkModel';


export default defineComponent({
    name: "Attr",

})
</script>
<script lang="ts" setup>


// 用来判断是否禁用保存按钮的计算属性
const isSaveDisabled = computed(() => {
    // 只有指定属性名及至少有一个属性值(必须有属性值名称)
    const hasName = !!attr.attrName
    // 判断属性值列表中是否至少有一个有属性值名称
    const hasAttrValue = attr.attrValueList.some(value => value.valueName)
    // 如果没有属性名或者没有属性值都是禁用的, 返回true
    return !hasName || !hasAttrValue
})



//请求保存属性
const save = async () => {
    // 发请求前整理/处理要提交的数据: attr
    //   删除属性值对象中的isEdit
    attr.attrValueList.forEach(value => delete value.isEdit)
    //   指定categoryId的值为category3Id.value
    attr.categoryId = category3Id.value as number
    // 发送添加/更新属性的请求
    await saveAttrApi(attr)
    // 成功后, 提示 / 回到列表页面/重新获取列表
    ElMessage.success('保存属性成功')
    isShowList.value = true
    getList()

}
// typeof: 得到类型
// InstanceType: 得到实例的类型   ==> 指定ref中的value保存el-input组件对象

const inputRef = ref<InstanceType<typeof ElInput>>()

//是否显示列表
//变为编辑模式
const toEdit = (row: AttrValueModel) => {
    //将isEdit 变为true
    row.isEdit = true
    // 通过ref得到ElInput, 并调用其focus方法获得焦点
    // 不行: 更新数据后, dom是异步更新的, 直接同步获取不到更新后dom
    // inputRef.value?.focus()
    // 解决: 等到dom更新后再去获取 => 使用nextTick
    nextTick(() => {
        inputRef.value?.focus()
    })

}
//变为查看模式
const toShow = (row: AttrValueModel, index: number) => {
    // 如果没有名称, 失去焦点时存在一个空行  ==> 删除这个属性值对象
    if (!row.valueName) {
        attr.attrValueList.splice(index, 1)
        return
    }
    // 如果与其它重名了, 失去焦点存在同名的2行 ==>  删除这个属性值对象


    //方式一如果有2个属性值对象的valueName等于row.valueName, 就重名了
    // const isRepeat = attr.attrValueList.filter(value => value.valueName === row.valueName).length === 2

    //方式二：如果除了自己外，还有一个的valueName等于row.valueName就重名了
    const isRepeat = attr.attrValueList.some(item => item != row && item.valueName === row.valueName)

    if (isRepeat) {
        attr.attrValueList.splice(index, 1)
        return
    }


    //将isEdit变为false
    row.isEdit = false
}

const isShowList = ref(true)
const initAttr = () => ({
    attrName: '',
    attrValueList: [],
    categoryId: 0,
    categoryLevel: 3
})

const attr = reactive<AttrModel>(initAttr())

//显示添加界面
const showAdd = () => {
    Object.assign(attr, initAttr())
    //显示
    isShowList.value = false
}
//显示更新页面
const showUpdate = (row: AttrModel) => {
    //将当前的指定函数的属性对象保存到attr中
    Object.assign(attr, row)
    // 共享同一个attrValueList, 里面的attrValue也是同一个 => 修改时就直接修改
    // Object.assign(attr, row)   
    // 解决办法: 使用lodash对row进行深拷贝
    Object.assign(attr, cloneDeep(row))
    //显示
    isShowList.value = false
}

const addAttrValue = () => {
    //创建一个函数
    const attrValue: AttrValueModel = {
        valueName: '',//属性值的名称
        attrId: attr.id,//属性的id
        isEdit: true//标识显示input
    }
    //添加到属性值列表中attr.attrValueList
    attr.attrValueList.push(attrValue)
    //自动获取焦点
    nextTick(() => inputRef.value?.focus())

}

//属性列表
const attrList = ref<AttrListModel>([])
//取出pinia管理的三级分类id
const { category1Id, category2Id, category3Id } = storeToRefs(useCategoryStore())
//监视category3Id
watch(category3Id, async (val) => {
    if (val) {
        // attrList.value = await getAttrListApi({
        //     category1Id: category1Id.value as number,
        //     category2Id: category2Id.value as number,
        //     category3Id: category3Id.value as number,
        // })
        getList()
    } else {
        //清空attrList
        attrList.value = []
    }
})
// 请求获取属性列表显示
async function getList() {
    // 请求获取属性列表, 并保存到attrList
    attrList.value = await getAttrListApi({
        category1Id: category1Id.value as number,
        category2Id: category2Id.value as number,
        category3Id: category3Id.value as number
    })
}
//删除指定属性
const remove = async (id: number) => {
    //请求删除接口
    await deleteAttrApi(id)
    //成功之后提示/重新获取列表
    ElMessage.success('删除成功!')
    getList()
}
</script>

<style scoped>
.avatar-uploader .avatar {
    width: 178px;
    height: 178px;
    display: block;
}
</style>

<style>
.avatar-uploader .el-upload {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
    border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    text-align: center;
}
</style>